﻿// ע�

using IoTClient;
using IotClientService.Handles;
using IotClientService.Handles.lgs;
using IotClientService.Handles.SimulatorHandle;
using IotClientService.Models.Lg;
using IotClientService.Models.Simulator;
using IotContract.Dtos.Clients.Equips;
using IotContract.Dtos.Servers;
using IotContract.Dtos.Servers.Pushs;
using IotContract.Events;
using IotContract.Interfaces;
using IotContract.Models.Clients;
using Mapster;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Extensions;
using XT.Common.Services;
using XT.MNet.Helpers;
using XT.MNet.Tcp;
using XT.MNet.Tcp.Options;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace IotClientService.Operations.Simulator;
public class EquipSimulatorOperation : IEquipOperation<SimulatorEquipDto>
{
    public event EventHandler<ConnectStatusEventArgs> OnConnectStatusChanged;

    public event EventHandler<string> Receive;

    public event EventHandler<string> Send;

    private IServiceProvider _provider;

    private CancellationTokenSource _cancellationTokenSource;

    private ILogService _logService;

    private bool _status = false;

    private LgTcpState _tcpState = LgTcpState.Closed;

    private SimulatorEquipDto _equipInfo;

    private TcpServer _sendServer;

    private TcpServer _recieveServer;

    private SimulatorHandleBase _simulatorHandle;

    private LgTcpServerHandle _tcpServerSendHandle;

    // tcp服务接收
    private LgTcpServerHandle _tcpServerReceiveHandle;


    public EquipSimulatorOperation(IServiceProvider provider, ILogService logService)
    {
        _provider = provider;
        _logService = logService;

    }

    public void Dispose()
    {
        throw new NotImplementedException();
    }

    public bool GetConnection()
    {
        return _tcpState == LgTcpState.Connected;
    }

    public SimulatorEquipDto GetEquipInfo()
    {
        throw new NotImplementedException();
    }

    public bool GetOperationStatus()
    {
        return _status;
    }

    public async Task<bool> Init(SimulatorEquipDto group, string ip, int port, CommandContent comContent,string equipType, IEnumerable<EquipTagDto> tags = null)
    {
        try
        {
            _equipInfo = group;
            // 获取设备对应的处理器
            _simulatorHandle = _provider.GetRequiredKeyedService<SimulatorHandleBase>(_equipInfo.EquipType);

            _simulatorHandle.Equip = _equipInfo;

            //创建一个Socket服务端
            _recieveServer = new TcpServer(new TcpServerOptions()
            {
             
                Address = ip,
                Port = (ushort)port,
                //Logger = debugLogger, // ILogger of your liking, default is just console one
                SpecialChar = '#' // only work for raw data
            });
          
            _recieveServer.On((data, conn) => {

                string recieve = Encoding.UTF8.GetString(data.ToArray());
                Receive.Invoke(null, recieve);
                _simulatorHandle.HandleData(recieve, comContent, equipType);

            });
            _simulatorHandle.SendMsgEvent += _simulatorHandle_SendMsgEvent;
            //添加断开连接事件
            if (_recieveServer != null)
            {
                _recieveServer.OnConnect += _recieveServer_OnConnect;
                _recieveServer.OnDisconnect += _recieveServer_OnDisconnect;
            }

            _recieveServer.Start();
            //_sendServer.Start();
            Send.Invoke(null, "开启Socket服务");

        }
        catch (Exception ex)
        {
            _equipInfo.Remark = $"Error Initial,Exception：{ex.Message}";
            OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
            {
                Connect = false,
                IsSuccess = true,
                Message = _equipInfo.Remark
            });
            return false;
        }
        return true;
    }

    private void _simulatorHandle_SendMsgEvent(object? sender, SimulatorGeneralDto e)
    {
        var result = _simulatorHandle.MsgHandle(e);

        var sendData = Encoding.UTF8.GetBytes(result);

        _recieveServer.Broadcast(sendData);

        Send.Invoke(null, result);
    }

    private void _sendServer_OnDisconnect(TcpServerConnection connection)
    {
        Send.Invoke(null, "客户端已断开连接");
    }

    private void _sendServer_OnConnect(TcpServerConnection connection)
    {
        Send.Invoke(null, "客户端已连接");
    }



    /// <summary>
    /// 断开事件
    /// </summary>
    /// <param name="connection"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void _recieveServer_OnDisconnect(TcpServerConnection connection)
    {
        _tcpState = LgTcpState.Closing;
        Send.Invoke(null, "客户端已断开连接");
    }

    /// <summary>
    /// 连接事件
    /// </summary>
    /// <param name="connection"></param>
    /// <exception cref="NotImplementedException"></exception>
    private void _recieveServer_OnConnect(TcpServerConnection connection)
    {
        _tcpState = LgTcpState.Connected;
        Send.Invoke(null, "客户端已连接");
    }

    public async Task  OperationStart()
    {
        _status = false;
        _recieveServer?.Stop();
        _tcpState = LgTcpState.Closed;
        _equipInfo.Remark = string.Empty;
        // 刷新推送的数据
        OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
        {
            Connect = false,
            IsSuccess = true,
        });
    }

    public async Task<bool> OperationStop()
    {
        _cancellationTokenSource?.Cancel();
        _status = false;

        OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
        {
            Connect = false,
            IsSuccess = true,
        });
        return true;
    }

    public async Task WriteRequest(string writeInfo)
    {
        if (writeInfo.IsNotNullOrEmpty())
        {
            var sendData = Encoding.UTF8.GetBytes(writeInfo);
            _recieveServer.Broadcast(sendData);
            Send.Invoke(this, writeInfo);
        }
    }

    /// <summary>
    /// 处理消息
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Handle_SendMsgEvent(object? sender, (PushSimulatorDto, SimulatorEquipDto) e)
    {

    }

    private void CancelPolling()
    {
        if (_cancellationTokenSource != null)
        {
            _cancellationTokenSource.Cancel();
            _cancellationTokenSource.Dispose();
            _cancellationTokenSource = null;
        }
    }

    public Task<bool> Init(SimulatorEquipDto group, IEnumerable<EquipTagDto> tags = null)
    {
        throw new NotImplementedException();
    }

    public Task<bool> WriteRequest(OperationWriteCommand writeInfo)
    {
        throw new NotImplementedException();
    }

    Task<bool> IEquipOperation<SimulatorEquipDto>.OperationStart()
    {
        throw new NotImplementedException();
    }
}
